﻿#include "ssSimpleHttp.h"
#include <fstream>
#include "../string/ssString.h"

namespace StarSeeker
{

ssSimpleHttp::ssSimpleHttp(u32 bufsz)
{
	m_buf.Init(bufsz);
	m_html = 0;
	m_htmlLen = 0;
}

bool ssSimpleHttp::QueryHtml( const char* ip, unsigned short port, const char* path )
{
	SOCKET s;
	int err = ConnectToServer(ip, port, s);
	if (err) return false;
	//Nonblock(s);

	m_buf.Empty();
	m_html = 0;
	m_htmlLen = 0;
	ssString quest(512);
	quest = "GET ";
	quest += path;
	quest += " HTTP/1.1\r\n";
	quest += "Host: ";
	quest += ip;
	quest += ":";
	quest += port;
	quest += "\r\n";
	quest += "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:19.0) Gecko/20100101 Firefox/19.0\r\n";
	quest += "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
	quest += "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
	//quest += "Accept-Encoding: gzip, deflate\r\n";
	quest += "DNT: 1";
	quest += "Connection: close\r\n\r\n";//keep-alive\r\n\r\n";

	int ret = send(s, quest.GetString(), quest.Size(), 0);
	if (ret<0)
		return false;
	do
	{
		ret = recv(s, m_buf.CurrentBuf(), m_buf.ResidueSize(), 0);
		if(ret>0)
		{
		   m_buf.AddSize(ret);
		}
	}
	while(ret>0);
	CloseOneSocket(s);

	return ExtractHtml();
}

void ssSimpleHttp::Print()
{
	if (m_html)
	{
		printf("**********************************\n");
		printf(m_html);
		printf("**********************************\n");
	}
}

bool ssSimpleHttp::ExtractHtml()
{
	if (m_buf.Buf()[9]!='2' || m_buf.Buf()[10]!='0' || m_buf.Buf()[11]!='0')
	{
		return false;
	}
	u32 enterFlag = 0;
	for (u32 i=0; i<m_buf.Size(); ++i)
	{
		if (m_buf.Buf()[i]=='\r' && m_buf.Buf()[i+1]=='\n' && m_buf.Buf()[i+2]=='\r' && m_buf.Buf()[i+3]=='\n')
		{
			enterFlag = i;
			m_html = m_buf.Buf() + i + 4;
			break;
		}
	}
	u32 lenFlag = 0;
	u32 lenFlag2 = 0;
	for (u32 i=0; i<m_buf.Size(); ++i)
	{
		if (m_buf.Buf()[i]=='C' && m_buf.Buf()[i+1]=='o' && m_buf.Buf()[i+2]=='n' && m_buf.Buf()[i+3]=='t' &&
			m_buf.Buf()[i+4]=='e' && m_buf.Buf()[i+5]=='n'  && m_buf.Buf()[i+6]=='t'  && m_buf.Buf()[i+7]=='-' &&
			m_buf.Buf()[i+8]=='L' && m_buf.Buf()[i+9]=='e' && m_buf.Buf()[i+10]=='n' && m_buf.Buf()[i+11]=='g' &&
			m_buf.Buf()[i+12]=='t' && m_buf.Buf()[i+13]=='h' && m_buf.Buf()[i+14]==':')
		{
			lenFlag = i + 16;
			for (u32 j=lenFlag; j<m_buf.Size(); ++j)
			{
				if (m_buf.Buf()[j]=='\r')
				{
					lenFlag2 = j;
					break;
				}
			}
			break;
		}
	}
	if (enterFlag>0 && lenFlag>0 && enterFlag>lenFlag && lenFlag2>lenFlag)
	{
		char num[32] = {0};
		memcpy(num, m_buf.Buf()+lenFlag, lenFlag2-lenFlag);
		m_htmlLen = ::atoi(num);
		return true;
	}
	return false;
}

bool ssSimpleHttp::Save2File(const char* path)
{
	if (m_html && m_htmlLen>0)
	{
		std::ofstream of(path);
		if (of.is_open())
		{
			of.write(m_html, m_htmlLen);
		}
		of.clear();
		of.close();
		return true;
	}
	return false;
}

}
